package com.moon.aop;

import com.google.common.util.concurrent.RateLimiter;
import com.moon.anno.Lmt;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Aspect
public class MyAop {
    //令牌桶集合
    Map<String, RateLimiter> map = new ConcurrentHashMap<String, RateLimiter>();

    @Pointcut("execution(* com.moon.controller.*.*(..))")
    public void p1() {
        //
    }

    @Around(value = "p1()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        String key = point.getSignature().toShortString();
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        Method method = methodSignature.getMethod();
        Lmt lmt = method.getDeclaredAnnotation(Lmt.class);
        if (lmt != null) {
            if (map.containsKey(key)) {
                RateLimiter rateLimiter = map.get(key);
                boolean flag = rateLimiter.tryAcquire();
                if (!flag) {
                    return null;
                }
            } else {
                RateLimiter rlmt = RateLimiter.create(lmt.value());
                map.put(key, rlmt);
            }
        }
        Object obj = point.proceed();
        return obj;
    }

    //
}
